<?php

namespace Hilaoyu\LaravelExtend\Services\Auth\Controllers;

use Hilaoyu\LaravelExtend\ControllerBase;
use Hilaoyu\LaravelExtend\Services\Auth\AuthService;
use Hilaoyu\LaravelExtend\Services\Captcha\CaptchaService;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

class LoginController extends ControllerBase
{
    use AuthenticatesUsers {
        logout as parentLogout;
        login as parentLogin;
        authenticated as parentAuthenticated;
        showLoginForm as parentShowLoginForm;
        sendFailedLoginResponse as parentSendFailedLoginResponse;
    }
    public function username()
    {
        return 'account';
    }

    public function redirectTo()
    {

        return \request()->input('logined_redirect', '/');
    }


    protected function userAlter($user)
    {
        return $user;
    }

    protected function tokenAlter($token)
    {
        return $token;
    }

    public function __construct()
    {
        //$this->middleware('guest')->except(['logout', 'login', 'loggedUser', 'showLogoutForm']);
    }

    protected function checkHasTooManyLoginAttempts(Request $request)
    {
        if (method_exists($this, 'hasTooManyLoginAttempts') &&
            $this->hasTooManyLoginAttempts($request)) {
            $this->fireLockoutEvent($request);

            return $this->sendLockoutResponse($request);
        }
    }


    public function showLoginForm(Request $request)
    {

        comResponse()->with(AuthService::GuardKey(), 'guard');
        return $this->renderingResponse();
    }

    public function LoginByMobile(Request $request)
    {
        $guard_key = AuthService::GuardKey();
        AuthService::LogOut($guard_key);
        if ($response = $this->checkHasTooManyLoginAttempts($request)) {
            return $response;
        }

        if (!AuthService::GetGuardProviderConfig($guard_key, 'allow_mobile_login')) {
            return $this->sendFailedLoginResponse($request);
        }

        $mobile = $request->input('mobile', "");
        $code_mobile_id = $request->input('code_mobile_id', "");
        $code_mobile_val = $request->input('code_mobile_val', "");

        $captchaService = new CaptchaService();
        if (!$captchaService->verify($code_mobile_id, $code_mobile_val, $mobile)) {
            return $this->sendFailedLoginResponse($request, [
//                'mobile' => trans('captcha.failed'),
                'code_mobile_val' => trans('captcha.mobile-failed'),
            ]);

        }

        $credentials = [
            'mobile' => $mobile
        ];
        $user = null;
        //如果作为客户端使用，先在用户中心注册
        if ($client = AuthService::ProviderUseAsClient()) {
            $user = $client->login('mobile', $credentials, $guard_key);

        } else {
            $user = AuthService::GuardCheckCredentials($guard_key, $credentials, false);
        }


        if ($user) {
            $user = AuthService::Login($guard_key, $user);
        }

        if ($user) {
            return $this->sendLoginResponse($request);
        }

        $this->incrementLoginAttempts($request);
        return $this->sendFailedLoginResponse($request);

    }

    public function LoginByEmail(Request $request)
    {
        $guard_key = AuthService::GuardKey();
        AuthService::LogOut($guard_key);
        if ($response = $this->checkHasTooManyLoginAttempts($request)) {
            return $response;
        }

        if (!AuthService::GetGuardProviderConfig($guard_key, 'allow_email_login')) {
            return $this->sendFailedLoginResponse($request);
        }

        $email = $request->input('email', "");
        $code_mobile_id = $request->input('code_email_id', "");
        $code_mobile_val = $request->input('code_email_val', "");

        $captchaService = new CaptchaService();
        if (!$captchaService->verify($code_mobile_id, $code_mobile_val, $email)) {
            return $this->sendFailedLoginResponse($request, [
                'email' => trans('auth.failed'),
            ]);

        }

        $credentials = [
            'email' => $email
        ];

        $user = null;
        //如果作为客户端使用，先在用户中心注册
        if ($client = AuthService::ProviderUseAsClient()) {
            $user = $client->login('email', $credentials, $guard_key);

        } else {
            $user = AuthService::GuardCheckCredentials($guard_key, $credentials, false);
        }

        if ($user) {
            $user = AuthService::Login($guard_key, $user);
        }

        if ($user) {
            return $this->sendLoginResponse($request);
        }
        $this->incrementLoginAttempts($request);
        return $this->sendFailedLoginResponse($request);

    }


    public function login(Request $request)
    {

        $guard_key = AuthService::GuardKey();
        AuthService::LogOut($guard_key);
        if ($response = $this->checkHasTooManyLoginAttempts($request)) {
            return $response;
        }

//        $this->limiter()->hit($this->throttleKey($request), $this->decayMinutes() * 60);
        $use_image_captcha = $show_image_captcha = false;
        if (AuthService::GetGuardProviderConfig($guard_key, 'login_use_image_captcha')) {
            if ($this->loginErrorLimitImageCaptcha() > 0) {
                if ($this->limiter()->tooManyAttempts($this->throttleKey($request), $this->loginErrorLimitImageCaptcha()-1)){
                    $show_image_captcha = true;
                }
                if ($this->limiter()->tooManyAttempts($this->throttleKey($request), $this->loginErrorLimitImageCaptcha())) {
                    $use_image_captcha = true;
                }
            } else {
                $use_image_captcha = $show_image_captcha = true;
            }
        }

        comResponse()->with($show_image_captcha, "show_image_captcha");


        $this->validateLogin($request);
        /*$request->validate([
            $this->username() => 'required|string',
            'password' => 'required|string',
        ]);*/
        if (!AuthService::GetGuardProviderConfig($guard_key, 'allow_account_login')) {
            return $this->sendFailedLoginResponse($request);
        }

        if ( $use_image_captcha && config('laravel-extend.services.captcha.registered', false) ) {
            $code_id = $request->input('code_img_id', '');
            $code_code_val = $request->input('code_img_val', '');
            $captchaService = new CaptchaService();
            if (!$captchaService->verify($code_id, $code_code_val,null,true)) {
                return $this->sendFailedLoginResponse($request, [
                    'code_img_val' => trans('captcha.failed'),
                ]);
            }
        }
        $user = null;
        //如果作为客户端使用，先在用户中心注册
        if ($client = AuthService::ProviderUseAsClient()) {
            $user = $client->login('account', $request->only(
                $this->username(),
                'password'
            ), $guard_key);
            if(!$user){
                comResponse()->withErrors($client->getError());
            }
        } else {
            $user = AuthService::GuardCheckCredentials($guard_key, $this->credentials($request), true);
        }
        if ($user) {
            $user = AuthService::Login($guard_key, $user);
        } 

        if ($user) {
            return $this->sendLoginResponse($request);
        }
        $this->incrementLoginAttempts($request);
        return $this->sendFailedLoginResponse($request);
    }


    public function showLogoutForm(Request $request)
    {
        comResponse()->with(AuthService::GuardKey(), 'guard');
        return $this->renderingResponse();
    }

    public function logout(Request $request)
    {
        AuthService::LogOut(AuthService::GuardKey());
        return $this->loggedOut($request) ?: redirect('/');
    }


    /**
     * The user has logged out of the application.
     *
     * @param \Illuminate\Http\Request $request
     * @return mixed
     */
    protected function loggedOut(Request $request)
    {
        if ($request->expectsJson()) {
            return comResponse()->success('退出成功')->json();
        }
    }


    /**
     * The user has been authenticated.
     *
     * @param \Illuminate\Http\Request $request
     * @param mixed $user
     * @param mixed $token
     * @return mixed
     * @throws ValidationException
     */
    protected function authenticated(Request $request, $user)
    {
        return $this->loggedUser($request);

    }


    public function loggedUser(Request $request)
    {
        if (!$guard = AuthService::Guard(AuthService::GuardKey())) {
            throw new AuthenticationException();
        }

        if (!$guard->check()) {
            throw new AuthenticationException();
        }


        $user = $this->userAlter($guard->user());
        $token = $this->tokenAlter($user->getAuthenticatedToken());


        if ($request->expectsJson()) {
            return comResponse()->success('登录成功')
                ->with(AuthService::AuthenticatedApiReturnData($user, $token))
                ->json();
        }
    }

    public function sendFailedLoginResponse(Request $request, $errors = array())
    {
        comResponse()->failed(trans('auth.failed'));
        $errors = (array)$errors;

        $error = AuthService::GetStaticError(false);
        if ($error) {
            $errors = [$this->username() => $error];
        }
        if(empty($errors)){
            $errors[$this->username()] = trans('auth.failed');
        }


        comResponse()->withErrors($errors);

        return $this->renderingResponse();
    }


    public function loginErrorLimitImageCaptcha()
    {
        return property_exists($this, 'loginErrorLimitImageCaptcha') ? (int)$this->loginErrorLimitImageCaptcha : 0;
    }

}
